#include "../utils/utils.hpp"
#include "literal.hpp"
#include "entity.hpp"

namespace mashine { namespace kb {

using namespace std;

Literal::Literal() : Entity<string>("", new vector<string *>())
{
	APP_LOGGER(info) << "Literal {" << "empty" << "} instantiated";
}

Literal::Literal(string name, vector<string *> * params, bool denied)
		: Entity<string>(name, params)
{
	this->denied = denied;
	
	APP_LOGGER(info) << "Literal {" << toString() << "} instantiated";
}

Literal::Literal(Literal const & literal) : Entity<string>(literal)
{
	APP_LOGGER(info) << "Literal {" << literal.toString() << "} copied";
}

Literal::~Literal()
{
	APP_LOGGER(info) << "Literal {" << toString() << "} begins to break down";
}

/**
 * need owerride this method in child class 
 * to correct work Entity constructor
 */
bool Literal::validateName(string & name) const
{
	APP_LOGGER(info) << "Literal {" << toString() << "} name validating begin";
	
	return utils::is_predicate_name(name);
}

/**
 * need owerride this method in child class 
 * to correct work Entity constructor
 */
bool Literal::validateParam(vector<string *> * params) const
{
	APP_LOGGER(info) << "Literal {" << toString() << "} params validating begin";
	
	for (vector<string *>::const_iterator i = params->begin(); i != params->end(); ++i)
    {
        if (utils::is_variable_name(**i) || utils::is_constant_name(**i) ) {} else 
		{
			return false;
		}
    }
	
	return true;
}

bool Literal::isFact() const
{
    for (vector<string *>::const_iterator i = params->begin(); i != params->end(); ++i) 
    {
        if (utils::is_variable_name(**i))
        {
            return false;
        }
    }

    return true;
}

bool Literal::isDenied() const
{
	return denied;
}

void Literal::setDenied(bool denied)
{
	this->denied = denied;
}

string Literal::toString() const
{
    string ret;

	if (denied) ret += "~";
	
    ret += *name;
		
    ret += "(";

    vector<string *>::const_iterator i;
    for (i = params->begin(); i != params->end(); i++)
    {	
		APP_LOGGER(info) << **i << ":";
		
		ret += **i;
        ret += ", ";
    }
	
	if (params->size() != 0) 
	{
		ret.erase(ret.size() - 2, 2);
    }
	
	ret += ")";

    return ret;
}

}}